package org.yidu.spider.controller;

import java.io.IOException;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.yidu.spider.bean.RegeditForm;
import org.yidu.spider.entity.UserInfo;
import org.yidu.spider.repository.UserInfoRepository;

@Controller
public class RegeditController {

    @Value("${rule.path}")
    private String rulesPath = "/data/rules/";

    @Autowired
    private UserInfoRepository userInfoRepository;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }

    @Autowired
    protected AuthenticationManager authenticationManager;

    @RequestMapping(value = "/regedit", method = RequestMethod.GET)
    public String regedit(Map<String, Object> model) {
        model.put("regeditForm", new RegeditForm());
        return "regedit";
    }

    @RequestMapping(value = "/regedit", method = RequestMethod.POST)
    @Transactional
    public String doRegedit(@Valid RegeditForm regeditForm, BindingResult bindingResult, HttpServletRequest request,
            HttpServletResponse response, ModelMap model) {

        if (bindingResult.hasErrors()) {
            return "regedit";
        }

        if (!StringUtils.equals(regeditForm.getPassword(), regeditForm.getRepassword())) {
            model.addAttribute("error", "两次输入的密码不一致！");
            return "regedit";
        }
        Integer count = userInfoRepository.countByUserName(regeditForm.getUsername());
        if (count > 0) {
            model.addAttribute("error", "用户名已存在！");
            return "regedit";
        }

        // 登录到数据库
        userInfoRepository.save(new UserInfo(regeditForm.getUsername(), regeditForm.getEmail(), regeditForm
                .getPassword()));
        authenticateUserAndSetSession(regeditForm.getUsername(), regeditForm.getPassword(), request);

        // copy默认规则
        Path src = Paths.get(rulesPath + "demo.xml");
        Path destDir = Paths.get(rulesPath + regeditForm.getUsername());
        Path dest = Paths.get(rulesPath + regeditForm.getUsername() + "/demo.xml");

        try {
            System.out.println(src);
            System.out.println(dest);
            Files.createDirectory(destDir);
            Files.copy(src, dest);
        } catch (IOException e) {
            System.out.println(e.getMessage());
            // do nothing
        }

        return "redirect:/";
    }

    private void authenticateUserAndSetSession(String username, String password, HttpServletRequest request) {

        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
        // generate session if one doesn't exist
        request.getSession();
        token.setDetails(new WebAuthenticationDetails(request));
        Authentication authenticatedUser = authenticationManager.authenticate(token);
        SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
    }
}
